package com.example.spring5.ms;

import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.atomic.LongAdder;

/**
 * @Author: Hu Rui
 * @Date: 2021/11/10 22:28
 */
public class RoundMethod {
    static LongAdder index = new LongAdder();
    /**
     * 轮询算法之随机轮询
     * @param serversMap 服务信息集合 key：服务名 value：int数字
     * @return 服务名
     */
    public static String randomRound(Map<String, Integer> serversMap) {
        if(serversMap == null || serversMap.isEmpty()){
            return null;
        }
        Set<String> keySet = serversMap.keySet();
        //保证有序
        List<String> serverNames = new ArrayList<>(keySet);
        Random random = new Random();
        int randomIndex = random.nextInt(serverNames.size());
        String serverName = serverNames.get(randomIndex);
        return serverName;
    }

    /**
     * 一般轮询算法
     * @param serversMap 服务信息集合 key：服务名 value：int数字
     * @return 服务名
     */
    public static String normalRound(Map<String, Integer> serversMap) {
        if(serversMap == null || serversMap.isEmpty()){
            return null;
        }
        Set<String> keySet = serversMap.keySet();
        //保证有序
        List<String> serverNames = new ArrayList<>(keySet);
        if (index.intValue() == serverNames.size()) {
            index.reset();
        }
        String serverName = serverNames.get(index.intValue());
        index.increment();
        return serverName;
    }


    /**
     * 一般加权轮询算法
     * @param serversMap 服务信息集合 key：服务名 value：int数字
     * @return 服务名
     */
    public static String weightRound(Map<String, Integer> serversMap) {
        if(serversMap == null || serversMap.isEmpty()){
            return null;
        }
        Set<String> keySet = serversMap.keySet();
        //保证有序
        List<String> serverNames = new ArrayList<>();
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            Integer weight = serversMap.get(next);
            for (int i = 0; i < weight; i++) {
                serverNames.add(next);
            }
        }
        if (index.intValue() == serverNames.size()) {
            index.reset();
        }
        String serverName = serverNames.get(index.intValue());
        index.increment();
        return serverName;
    }

    /**
     * 随机加权轮询算法
     * @param serversMap 服务信息集合 key：服务名 value：int数字
     * @return 服务名
     */
    public static String randomWeightRound(Map<String, Integer> serversMap) {
        if(serversMap == null || serversMap.isEmpty()){
            return null;
        }
        Set<String> keySet = serversMap.keySet();
        //保证有序
        List<String> serverNames = new ArrayList<>();
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            Integer weight = serversMap.get(next);
            for (int i = 0; i < weight; i++) {
                serverNames.add(next);
            }
        }
        Random random = new Random();
        int index = random.nextInt(serverNames.size());
        String serverName = serverNames.get(index);
        return serverName;
    }

    /**
     * IP哈希轮询算法
     * @param serversMap 服务信息集合 key：服务名 value：int数字
     * @return 服务名
     */
    public static String ipHashRound(Map<String, Integer> serversMap,String clientIP) {
        if(serversMap == null || serversMap.isEmpty() || clientIP == null){
            return null;
        }
        Set<String> keySet = serversMap.keySet();
        //保证有序
        List<String> serverNames = new ArrayList<>(keySet);
        //hashcode取值范围 -2^31到2^31-1
        int ipHashCode = Math.abs(clientIP.hashCode());
        int size = serverNames.size();
        int index = ipHashCode % size;
        System.out.println(index);
        String serverName = serverNames.get(index);
        return serverName;
    }

    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("192.168.2.5", 1);
        map.put("192.168.2.6", 1);
        map.put("192.168.2.7", 1);
        map.put("192.168.2.8", 1);
        for (int i = 0; i < 5; i++) {
            System.out.println(ipHashRound(map,"192.168.2.122"));
        }
        System.out.println();
        for (int i = 0; i < 5; i++) {
            System.out.println(ipHashRound(map,"192.168.2.123"));
        }
        System.out.println();
        for (int i = 0; i < 5; i++) {
            System.out.println(ipHashRound(map,"192.168.2.124"));
        }
        System.out.println();
        for (int i = 0; i < 5; i++) {
            System.out.println(ipHashRound(map,"192.168.2.125"));
        }
    }
}
